package com.wildlife.springboot.controller;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wildlife.springboot.common.Result;
import com.wildlife.springboot.entity.AllCategories;
import com.wildlife.springboot.entity.AllCategories;
import com.wildlife.springboot.mapper.service.ImageUploadService;
import com.wildlife.springboot.mapper.service.MolecularSequenceUploadService;
import com.wildlife.springboot.mapper.service.SoundUploadService;
import com.wildlife.springboot.mapper.service.VideoUploadService;
import com.wildlife.springboot.service.IAllCategoriesService;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/allCategories")
public class AllCategoriesController {
    @Resource
    private IAllCategoriesService allCategoriesService;

    @Resource
    private ImageUploadService imageUploadService;

    @Resource
    private VideoUploadService videoUploadService;

    @Resource
    private SoundUploadService soundUploadService;

    @Resource
    private MolecularSequenceUploadService molecularSequenceUploadService;


    //新增和修改
    @PostMapping
    public Result save(@RequestBody AllCategories AllCategories){
        //新增或更新
        return Result.success(allCategoriesService.saveOrUpdate(AllCategories));
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        return Result.success(allCategoriesService.removeById(id));
    }

    @PostMapping ("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids){
        return Result.success(allCategoriesService.removeByIds(ids));
    }

    // 获取所有濒危野生动物信息的接口
    @GetMapping("/all")
    public Result findAnimalAll() {
        List<AllCategories> wildlifeList = allCategoriesService.list();
        if (wildlifeList != null && !wildlifeList.isEmpty()) {
            return Result.success(wildlifeList);
        } else {
            return Result.fail("未找到任何濒危野生动物信息");
        }
    }

    @GetMapping
    public Result findAll() {
        return Result.success(allCategoriesService.list());
    }

    @GetMapping("/{id}")
    public Result findOne(@PathVariable Integer id) {
        return Result.success(allCategoriesService.getById(id));
    }

    @GetMapping("/chineseName/{chineseName}")
    public Result findOne(@PathVariable String chineseName) {
        QueryWrapper<AllCategories> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("chinese_name", chineseName);
        return Result.success(allCategoriesService.getOne(queryWrapper));
    }

    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           @RequestParam(defaultValue = "") String chineseName
    ) {
        QueryWrapper<AllCategories> queryWrapper = new QueryWrapper<>();
        if (!"".equals(chineseName)) {
            queryWrapper.like("chinese_name", chineseName);
        }
        return Result.success(allCategoriesService.page(new Page<>(pageNum, pageSize), queryWrapper));
    }

    // 导出接口
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws Exception {
        // 从数据库查询出所有的数据
        List<AllCategories> list = allCategoriesService.list();
        // 通过工具类创建writer 写出到磁盘路径

        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 自定义标题别名
        writer.addHeaderAlias("id", "ID");
        writer.addHeaderAlias("chineseName", "中文名");
        writer.addHeaderAlias("imageUrl", "图片路径");
        writer.addHeaderAlias("videoUrl", "视频路径");
        writer.addHeaderAlias("molecularSequence", "分子序列");
        writer.addHeaderAlias("soundUrl", "鸣声");

        writer.write(list, true);

        // 设置浏览器相应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("珍稀濒危动物", StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
    }

    // 导入接口
    // reader.addHeaderAlias(): 忽略表头的中文
    @PostMapping("/import")
    public Boolean imp(MultipartFile file) throws Exception {
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        reader.addHeaderAlias("ID", "id");
        reader.addHeaderAlias("中文名", "chineseName");
        reader.addHeaderAlias("图片路径", "chineseName");
        reader.addHeaderAlias("视频路径", "imageUrl");
        reader.addHeaderAlias("分子序列", "molecularSequence");
        reader.addHeaderAlias("鸣声", "soundUrl");

        List<AllCategories> list = reader.readAll(AllCategories.class);
        allCategoriesService.saveBatch(list);
        return true;
    }

    @PostMapping("/upload")
    public Result uploadImage(@RequestParam("files") List<MultipartFile> files) {
        try {
            // 上传多个图片
            List<String> urls = imageUploadService.uploadImages(files);
            // 返回多个图片路径
            return Result.success(urls);
        } catch (Exception e) {
            return Result.fail("上传失败");
        }
    }

    @PostMapping("/uploadFeces")
    public Result uploadFeces(@RequestParam("files") List<MultipartFile> files) {
        try {
            // 上传多个图片
            List<String> urls = imageUploadService.uploadImages(files);
            // 返回多个图片路径
            return Result.success(urls);
        } catch (Exception e) {
            return Result.fail("上传失败");
        }
    }
    @PostMapping("/uploadHair")
    public Result uploadHair(@RequestParam("files") List<MultipartFile> files) {
        try {
            // 上传多个图片
            List<String> urls = imageUploadService.uploadImages(files);
            // 返回多个图片路径
            return Result.success(urls);
        } catch (Exception e) {
            return Result.fail("上传失败");
        }
    }
    @PostMapping("/uploadFootprint")
    public Result uploadFootprint(@RequestParam("files") List<MultipartFile> files) {
        try {
            // 上传多个图片
            List<String> urls = imageUploadService.uploadImages(files);
            // 返回多个图片路径
            return Result.success(urls);
        } catch (Exception e) {
            return Result.fail("上传失败");
        }
    }
    @PostMapping("/uploadSkeleton")
    public Result uploadSkeleton(@RequestParam("files") List<MultipartFile> files) {
        try {
            // 上传多个图片
            List<String> urls = imageUploadService.uploadImages(files);
            // 返回多个图片路径
            return Result.success(urls);
        } catch (Exception e) {
            return Result.fail("上传失败");
        }
    }

    // 上传多个视频
    @PostMapping("/uploadVideos")
    public Result uploadVideos(@RequestParam("files") List<MultipartFile> files,
                               @RequestParam("id") Integer id) {
        try {
            List<Map<String, String>> filesInfo = videoUploadService.uploadVideos(files);

            // 提取路径和原始文件名
            String videoPaths = filesInfo.stream()
                    .map(f -> f.get("path"))
                    .collect(Collectors.joining(","));

            String videoNames = filesInfo.stream()
                    .map(f -> f.get("originalFilename"))
                    .collect(Collectors.joining(","));

            // 更新数据库记录
            AllCategories allCategories = allCategoriesService.getById(id);
            if (allCategories != null) {
                allCategories.setVideoUrl(videoPaths);
                allCategories.setVideoNames(videoNames);
                allCategoriesService.updateById(allCategories);
            }

            return Result.success(filesInfo);
        } catch (Exception e) {
            return Result.fail("上传失败: " + e.getMessage());
        }
    }

    // 查看所有上传的视频
    @GetMapping("/viewVideos")
    public Result viewVideos(@RequestParam("paths") String paths) {
        try {
            List<Map<String, String>> videos = new ArrayList<>();
            String[] pathArray = paths.split(",");
            for (String path : pathArray) {
                Map<String, String> videoData = new HashMap<>();
                videoData.put("path", path);
                videoData.put("filename", path.substring(path.lastIndexOf("/") + 1));
                videos.add(videoData);
            }
            return Result.success(videos);
        } catch (Exception e) {
            return Result.fail("获取视频列表失败: " + e.getMessage());
        }
    }

    // 上传多个鸣声文件
    @PostMapping("/uploadSounds")
    public Result uploadSounds(@RequestParam("files") List<MultipartFile> files,
                               @RequestParam("id") Integer id) {
        try {
            List<Map<String, String>> filesInfo = soundUploadService.uploadSounds(files);

            // 提取路径和原始文件名
            String sound = filesInfo.stream()
                    .map(f -> f.get("path"))
                    .collect(Collectors.joining(","));

            String soundNames = filesInfo.stream()
                    .map(f -> f.get("originalFilename"))
                    .collect(Collectors.joining(","));

            // 更新数据库记录
            AllCategories allCategories = allCategoriesService.getById(id);
            if (allCategories != null) {
                allCategories.setSoundUrl(sound);
                allCategories.setSoundNames(soundNames);
                allCategoriesService.updateById(allCategories);
            }

            return Result.success(filesInfo);
        } catch (Exception e) {
            return Result.fail("上传失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/deleteSoundsUrl")
    public Result deleteSoundsUrl(@RequestParam("id") Long id,
                                  @RequestParam("filePath") String filePath) {
        if (id == null || filePath == null || filePath.trim().isEmpty()) {
            return Result.fail("请求参数错误：id 或 filePath 不能为空");
        }

        AllCategories allCategories = allCategoriesService.getById(id);
        if (allCategories == null) {
            return Result.fail("记录不存在");
        }

        String sound = allCategories.getSoundUrl();
        if (sound == null || sound.isEmpty()) {
            return Result.fail("没有分子序列文件");
        }

        List<String> filePaths = new ArrayList<>(Arrays.asList(sound.split(",")));
        String normalizedFilePath = filePath.trim();
        boolean removed = filePaths.removeIf(path -> path.trim().equals(normalizedFilePath));

        if (!removed) {
            return Result.fail("文件路径不存在：" + filePath);
        }

        // 更新数据库中的文件路径
        allCategories.setSoundUrl(String.join(",", filePaths));
        boolean isUpdated = allCategoriesService.updateById(allCategories);

        if (!isUpdated) {
            return Result.fail("删除失败，数据库更新未生效");
        }

        return Result.success("删除成功");
    }

    // 查看所有鸣声数据内容
    @GetMapping("/viewSoundsUrl")
    public Result viewSoundsUrl(@RequestParam("paths") String paths) {
        try {
            List<Map<String, String>> contents = new ArrayList<>();
            String[] pathArray = paths.split(",");
            for (String path : pathArray) {
                String content = soundUploadService.readFileContent(path);

                // 提取原始文件名
                String originalFilename = path.substring(path.lastIndexOf("/") + 1); // 获取 UUID 文件名
                originalFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")); // 去掉后缀

                Map<String, String> fileData = new HashMap<>();
                fileData.put("path", path);
                fileData.put("content", content);
                fileData.put("originalFilename", originalFilename);
                contents.add(fileData);
            }
            return Result.success(contents);
        } catch (Exception e) {
            return Result.fail("读取文件失败: " + e.getMessage());
        }
    }

    @PostMapping("/uploadMolecularSequences")
    public Result uploadMolecularSequences(@RequestParam("files") List<MultipartFile> files,
                                           @RequestParam("id") Integer id) {
        try {
            List<Map<String, String>> filesInfo = molecularSequenceUploadService.uploadMolecularSequences(files);

            // 提取路径和原始文件名
            String molecularSequence = filesInfo.stream()
                    .map(f -> f.get("path"))
                    .filter(Objects::nonNull)  // 避免 null 值
                    .collect(Collectors.joining(","));

            String molecularNames = filesInfo.stream()
                    .map(f -> f.get("originalFilename"))
                    .filter(Objects::nonNull)  // 避免 null 值
                    .collect(Collectors.joining(","));

            // 更新数据库记录
            AllCategories allCategories = allCategoriesService.getById(id);
            if (allCategories != null) {
                if (allCategories.getMolecularSequence() != null && !allCategories.getMolecularSequence().isEmpty()) {
                    molecularSequence = allCategories.getMolecularSequence() + "," + molecularSequence;
                }
                if (allCategories.getMolecularNames() != null && !allCategories.getMolecularNames().isEmpty()) {
                    molecularNames = allCategories.getMolecularNames() + "," + molecularNames;
                }

                allCategories.setMolecularSequence(molecularSequence);
                allCategories.setMolecularNames(molecularNames);
                allCategoriesService.updateById(allCategories);
            }

            return Result.success(filesInfo);
        } catch (Exception e) {
            return Result.fail("上传失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/deleteMolecularSequence")
    public Result deleteMolecularSequence(@RequestParam("id") Long id,
                                          @RequestParam("filePath") String filePath) {
        if (id == null || filePath == null || filePath.trim().isEmpty()) {
            return Result.fail("请求参数错误：id 或 filePath 不能为空");
        }

        AllCategories allCategories = allCategoriesService.getById(id);
        if (allCategories == null) {
            return Result.fail("记录不存在");
        }

        String molecularSequence = allCategories.getMolecularSequence();
        String molecularNames = allCategories.getMolecularNames(); // 获取原始文件名
        if (molecularSequence == null || molecularSequence.isEmpty() ||
                molecularNames == null || molecularNames.isEmpty()) {
            return Result.fail("没有分子序列文件");
        }

        List<String> filePaths = new ArrayList<>(Arrays.asList(molecularSequence.split(",")));
        List<String> fileNames = new ArrayList<>(Arrays.asList(molecularNames.split(",")));

        String normalizedFilePath = filePath.trim();
        int index = filePaths.indexOf(normalizedFilePath);

        if (index == -1) {
            return Result.fail("文件路径不存在：" + filePath);
        }

        // **删除对应的文件路径和原始文件名**
        filePaths.remove(index);
        fileNames.remove(index);

        // 更新数据库
        allCategories.setMolecularSequence(String.join(",", filePaths));
        allCategories.setMolecularNames(String.join(",", fileNames));
        boolean isUpdated = allCategoriesService.updateById(allCategories);

        if (!isUpdated) {
            return Result.fail("删除失败，数据库更新未生效");
        }

        return Result.success("删除成功");
    }



    @GetMapping("/viewMolecularSequences")
    public Result viewMolecularSequences(@RequestParam("paths") String paths, @RequestParam("names") String names) {
        try {
            List<Map<String, String>> contents = new ArrayList<>();
            String[] pathArray = paths.split(",");
            String[] nameArray = names.split(","); // 获取原始文件名数组

            if (pathArray.length != nameArray.length) {
                return Result.fail("文件路径和原始文件名数量不匹配");
            }

            for (int i = 0; i < pathArray.length; i++) {
                String path = pathArray[i];
                String content = molecularSequenceUploadService.readFileContent(path);
                String originalFilename = nameArray[i]; // 直接使用原始文件名

                Map<String, String> fileData = new HashMap<>();
                fileData.put("path", path);
                fileData.put("content", content);
                fileData.put("originalFilename", originalFilename);
                contents.add(fileData);
            }
            return Result.success(contents);
        } catch (Exception e) {
            return Result.fail("读取文件失败: " + e.getMessage());
        }
    }


    @GetMapping("/details/{id}")
    public Result getAnimalDetails(@PathVariable("id") Long id) {
        AllCategories allCategories = allCategoriesService.getById(id);
        if (allCategories != null) {
            int imageCount = Optional.ofNullable(allCategories.getImageUrls())
                    .filter(urls -> !urls.trim().isEmpty())
                    .map(urls -> (int) Arrays.stream(urls.split(","))
                            .filter(url -> !url.trim().isEmpty())
                            .count())
                    .orElse(0);
            int videoCount = Optional.ofNullable(allCategories.getVideoUrl())
                    .filter(seq -> !seq.trim().isEmpty())
                    .map(seq -> (int) Arrays.stream(seq.split(","))
                            .filter(s -> !s.trim().isEmpty())
                            .count())
                    .orElse(0);
            int soundCount = Optional.ofNullable(allCategories.getSoundUrl())
                    .filter(seq -> !seq.trim().isEmpty())
                    .map(seq -> (int) Arrays.stream(seq.split(","))
                            .filter(s -> !s.trim().isEmpty())
                            .count())
                    .orElse(0);
            int molecularCount = Optional.ofNullable(allCategories.getMolecularSequence())
                    .filter(seq -> !seq.trim().isEmpty())
                    .map(seq -> (int) Arrays.stream(seq.split(","))
                            .filter(s -> !s.trim().isEmpty())
                            .count())
                    .orElse(0);
            Map<String, Object> details = new HashMap<>();
            details.put("id", allCategories.getId());
            details.put("chineseName", allCategories.getChineseName());
            details.put("imageCount", imageCount);
            details.put("videoCount", videoCount);
            details.put("soundCount", soundCount);
            details.put("molecularCount", molecularCount);

            return Result.success(details);
        } else {
            return Result.fail("未找到该动物信息");
        }
    }

    // 获取卡片数据
    @GetMapping("/cards")
    public Result findAllForCards() {
        List<AllCategories> list = allCategoriesService.list();
        return Result.success(list);
    }

}
